/*
 * TowerUpgradeRange.cs
 *
 * Created on January 19, 2008, 11:57 AM
 *
 * Copyright (C) 2007-2008  Hylke van der Schaaf
 * Copyright (C) 2010       Mathijs Miermans
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, in version 3 of the License.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace HexTD
{
	public class TowerUpgradeRange : TowerBase
	{
		public static int price = 0;
		public static int damage = 0;
		public static float range = 4.3f;

		private List<Tower> clients = new List<Tower>();
#if PORT
		private LineSegment[] clientLines;
		private Brush clientStroke;
#endif
		private Color clientColor;

		/** Creates a new instance of TowerUpgradeRange */
		public TowerUpgradeRange(Game game, Context context, Hex hex)
			: base(game, TowerFactory.type.upgradeRange, price, damage, range)
		{
			this.lineColor = new Color(255, 200, 200, 200);
			this.clientColor = new Color(255, 50, 255, 50);
			this.clients = new List<Tower>();

			this.doInit(context, hex);
			this.pts = null;
#if PORT
			context.loadSvg("upgradeRange", "images\\upgradeRange.svg");
#endif

			this.context.towerBuild += new EventHandler(towerBuild);
			this.context.towerRemoved += new EventHandler(towerRemoved);
			this.scanTowers();
		}

		private void scanTowers()
		{
			if (!this.selling)
			{
				float dx, dy;
				float[] loc;
				foreach (Tower t in this.context.towers)
				{
					if (!this.clients.Contains(t))
					{
						loc = t.getHex().getFloatLocation();
						dx = this.xFloat - loc[0];
						dy = this.yFloat - loc[1];
						if ((dx * dx + dy * dy) < this.rangeCurrent2)
						{
							t.registerTower(this);
						}
					}
					else
					{
						loc = t.getHex().getFloatLocation();
						dx = this.xFloat - loc[0];
						dy = this.yFloat - loc[1];
						if ((dx * dx + dy * dy) > this.rangeCurrent2)
						{
							t.unregisterTower(this);
						}
					}
				}
			}
		}

		protected override void calcDamageRange()
		{
			base.calcDamageRange();
			this.scanTowers();
		}

		public override bool canUpgrade()
		{
			return false;
		}

		public override string getStatusString()
		{
			string retString = "";
			retString += "<h1>Range Upgrade</h1>" +
					"<p>" +
					"Increases the range of other towers, including other upgrade towers.<br>" +
					"<b>Towers affected:</b> " + this.clients.Count + "<br>\n" +
					"<b>Range:</b> " + this.rangeText + "<br>" +
					"</p>\n";
			return retString;
		}

		public override string getInfoString()
		{
			string retString = "";
			retString += "<h1>Range Upgrade</h1>" +
					"<p>Increases the range of other towers.</p>" +
					"<p class='warn'>This tower costs 1 bonus point.</p>";
			return retString;
		}

		public override void doTick(int gameTime)
		{
		}

		public void towerBuild(object sender, EventArgs e)
		{
			Tower t = (Tower)e;
			if (t != this && !this.selling && !this.clients.Contains(t))
			{
				float dx, dy;
				float[] loc;
				loc = t.getHex().getFloatLocation();
				dx = this.xFloat - loc[0];
				dy = this.yFloat - loc[1];
				if ((dx * dx + dy * dy) < this.rangeCurrent2)
				{
					t.registerTower(this);
				}
			}
		}
		public void towerRemoved(object sender, EventArgs e)
		{
			Tower t = (Tower)e;
			if (this.clients.Contains(t))
			{
				t.unregisterTower(this);
			}
		}
		public void addClient(Tower t)
		{
			if (!this.selling && !this.clients.Contains(t))
			{
				this.clients.Add(t);
				this.generateShapes();
			}
		}
		public void removeClient(Tower t)
		{
			this.clients.Remove(t);
			this.generateShapes();
		}

		public override void doCleanup()
		{
			base.doCleanup();
			for (int i = this.clients.Count - 1; i >= 0; i--)
			{
				Tower t = this.clients[i];
				t.unregisterTower(this);
			}
#if PORT
			this.context.removeTowerListener(this);
#endif
		}

		public override string getSvgName()
		{
			return "upgradeRange";
		}

		protected override void generateShapes()
		{
#if PORT
			float cx = +0;
			float cy = +0;

			this.clientLines = new LineSegment[this.clients.Count];
			float[] from;
			float[] to = this.getHex().getPaintLocation();
			to[0] += cx;
			to[1] += cy;
			for (int i = 0; i < this.clientLines.Length; i++)
			{
				from = this.clients[i].getHex().getPaintLocation();
				this.clientLines[i] = new LineSegment.Float(from[0], from[1], to[0], to[1]);
			}
			this.clientStroke = new Brush(1.0f * this.context.strokeScale, Brush.CAP_ROUND, Brush.JOIN_BEVEL);
#endif
		}

		public override void DrawEffects(GameTime gameTime)
		{
#if PORT
			g2.setStroke(this.clientStroke);
			g2.setColor(this.clientColor);
			for (int i = 0; i < this.clientLines.Length; i++)
			{
				g2.draw(this.clientLines[i]);
			}
#endif
		}

	}
}